package cn.itcast.demo;

import org.apache.lucene.document.Document;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.queryparser.classic.ParseException;
import org.apache.lucene.queryparser.classic.QueryParser;
import org.apache.lucene.search.*;
import org.apache.lucene.search.highlight.*;
import org.apache.lucene.search.highlight.Scorer;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.junit.Test;
import org.wltea.analyzer.lucene.IKAnalyzer;

import java.io.File;
import java.io.IOException;

@SuppressWarnings("all")
public class LuceneIndexSuperQuery {

    @Test
    public void testHighLightQuery() throws IOException, ParseException, InvalidTokenOffsetsException {
        //目录
        Directory directory = FSDirectory.open(new File("indexDir"));

        //把目录中的数据或内容全部读取出来
        IndexReader indexReader = DirectoryReader.open(directory);

        //索引的查询对象，或者叫索引的检索对象
        IndexSearcher searcher = new IndexSearcher(indexReader);

        QueryParser queryParser = new QueryParser("title", new IKAnalyzer());

        Query query = queryParser.parse("加盟");

        //搜索条件，执行搜索，需要传入搜索条件，以及要搜索的数量,返回符合条件的前N个文档
        TopDocs topDocs = searcher.search(query, Integer.MAX_VALUE);
        //表示实际命中的个数
        int totalHits = topDocs.totalHits;
        System.out.println("命中了 = " + totalHits);

        //得分文档数组
        ScoreDoc[] scoreDocs = topDocs.scoreDocs;
        int length = scoreDocs.length;

        System.out.println("真正的查到的数量=" + length);
//      准备高亮的两个参数
        Formatter formatter = new SimpleHTMLFormatter("<em>", "</em>");
        Scorer scorer = new QueryScorer(query);
        // 准备高亮的工具
        Highlighter highlighter = new Highlighter(formatter, scorer);

        for (ScoreDoc scoreDoc : scoreDocs) {
            System.out.println("======================");
            //当前文档的得分
            float score = scoreDoc.score;
            //当前文档的编号
            int docId = scoreDoc.doc;

            Document document = searcher.doc(docId);

            String id = document.get("id");
            //对title进行二次分词
            String titleValue = document.get("title");
            //执行高亮,进行二次分词以及组合，直接返回最终高亮的结果
            String highLightTitle = highlighter.getBestFragment(new IKAnalyzer(), "title", titleValue);
            System.out.println("得分:" + score + "id:" + id + "title:" + highLightTitle);
        }
        System.err.println("红");

    }

    @Test
    public void testSortQuery() throws IOException, ParseException, InvalidTokenOffsetsException {
        //目录
        Directory directory = FSDirectory.open(new File("indexDir"));

        //把目录中的数据或内容全部读取出来
        IndexReader indexReader = DirectoryReader.open(directory);

        //索引的查询对象，或者叫索引的检索对象
        IndexSearcher searcher = new IndexSearcher(indexReader);

        QueryParser queryParser = new QueryParser("title", new IKAnalyzer());

        Query query = queryParser.parse("加盟");
        //三个参数分别表示排序字段的名称，类型以及是否倒序
        Sort sort = new Sort(new SortField("id", SortField.Type.LONG, true));

        //搜索条件，执行搜索，需要传入搜索条件，以及要搜索的数量,返回符合条件的前N个文档,以及排序条件
        TopDocs topDocs = searcher.search(query, Integer.MAX_VALUE, sort);
        //表示实际命中的个数
        int totalHits = topDocs.totalHits;
        System.out.println("命中了 = " + totalHits);

        //得分文档数组
        ScoreDoc[] scoreDocs = topDocs.scoreDocs;
        int length = scoreDocs.length;

        System.out.println("真正的查到的数量=" + length);

        for (ScoreDoc scoreDoc : scoreDocs) {
            System.out.println("======================");
            //当前文档的得分
            float score = scoreDoc.score;
            //当前文档的编号
            int docId = scoreDoc.doc;

            Document document = searcher.doc(docId);

            String id = document.get("id");
            //对title进行二次分词
            String title = document.get("title");

            System.out.println("得分:" + score + "id:" + id + "title:" + title);
        }
    }

    @Test
    public void testPageQuery() throws IOException, ParseException, InvalidTokenOffsetsException {

        int currentPage = 3;
        final int PAGE_SIZE = 2;
        int start = (currentPage - 1) * PAGE_SIZE;
        int end = currentPage * PAGE_SIZE;
        //目录
        Directory directory = FSDirectory.open(new File("indexDir"));

        int total = -1;
        int toalPage = -1;

        //把目录中的数据或内容全部读取出来
        IndexReader indexReader = DirectoryReader.open(directory);

        //索引的查询对象，或者叫索引的检索对象
        IndexSearcher searcher = new IndexSearcher(indexReader);

        QueryParser queryParser = new QueryParser("title", new IKAnalyzer());

        Query query = queryParser.parse("谷歌");
        //三个参数分别表示排序字段的名称，类型以及是否倒序
        Sort sort = new Sort(new SortField("id", SortField.Type.LONG, true));

        //搜索条件，执行搜索，需要传入搜索条件，以及要搜索的数量,返回符合条件的前N个文档,以及排序条件
        TopDocs topDocs = searcher.search(query, Integer.MAX_VALUE, sort);
        //表示实际命中的个数
        int totalHits = topDocs.totalHits;
        System.out.println("命中了 = " + totalHits);

        //得分文档数组
        ScoreDoc[] scoreDocs = topDocs.scoreDocs;
        int length = scoreDocs.length;

        System.out.println("真正的查到的数量=" + length);
        //实际的总个数
        total = scoreDocs.length;
        //计算总页数
        toalPage = total % PAGE_SIZE == 0 ? total / PAGE_SIZE : total / PAGE_SIZE + 1;

        if (currentPage > toalPage) {
            System.out.println("当前页太大，容不下，只有：" + toalPage + "页");
        } else if (currentPage == toalPage) {
            end = total;
        }

        for (int i = start; i < end; i++) {
            ScoreDoc scoreDoc = scoreDocs[i];
            System.out.println("======================");

            //当前文档的得分
            float score = scoreDoc.score;
            //当前文档的编号
            int docId = scoreDoc.doc;

            Document document = searcher.doc(docId);

            String id = document.get("id");
            //对title进行二次分词
            String title = document.get("title");

            System.out.println("得分:" + score + "id:" + id + "title:" + title);
        }
//        for (ScoreDoc scoreDoc : scoreDocs) {
//            System.out.println("======================");
//            //当前文档的得分
//            float score = scoreDoc.score;
//            //当前文档的编号
//            int docId = scoreDoc.doc;
//
//            Document document = searcher.doc(docId);
//
//            String id = document.get("id");
//            //对title进行二次分词
//            String title = document.get("title");
//
//            System.out.println("得分:"+score+"id:"+id+"title:"+title);
//        }
    }
}
